#include "AID.h"

aid::aid(string name, list<string> addresses) {
	_name = name;
	_addresses = addresses;
	return;
};

aid::aid(string name, list<string> addresses, list<string> resolvers) {
	aid(name, addresses);
	_resolvers = resolvers;
	return;
};

aid::aid(string name, list<string> addresses, list<string> resolvers, map<string,string> userDefinedProperties) {
	aid(name, addresses, resolvers);
	_userDefinedProperties = userDefinedProperties;
	return;
};

string aid::getName() {
	return _name;	
};

void aid::setName(string name) {
	_name = name;
	return;
};

list<string> aid::getAddresses() {
	return _addresses;
};

void aid::addAddress(string addr) {
	_addresses.push_back(addr);
	return;
};

list<string> aid::getResolvers() {
	return _resolvers;
};

void aid::addResolver(string resolver) {
	_resolvers.push_back(resolver);
};

map<string,string> aid::getProperties() {
	return _userDefinedProperties;
};

void aid::addProperty(string prop, string value) {
	_userDefinedProperties[prop] = value;
	return;
};

bool aid::operator== (aid &other)  {
	// Check name
	if (_name != other.getName()) return false;

	// Check addresses
	list<string>::iterator i,j;
	list<string> ad = other.getAddresses();
	bool found;
	
	// Search for every address in the other aid
	for ( i = _addresses.begin() ; i != _addresses.end() ; i++ ) {
		found = false;
		for ( j = ad.begin() ; j != ad.end() ; j++ ) {
			if (*i == *j) {
				found = true;
				break;
			};
		};
		if (!found) return found;
	};
	
	// Check resolvers
	// Search for every resolver in the other aid
	found = false;
	ad = other.getResolvers();
	for ( i = _resolvers.begin() ; i != _resolvers.end() ; i++ ) {
		found = false;
		for ( j = ad.begin() ; j != ad.end() ; j++ ) {
			if (*i == *j) {
				found = true;
				break;
			};
		};
		if (!found) return found;
	};
	
	// Check user defined properties
	map<string,string>::iterator k,l;
	map<string,string> u;
	found = false;
	for ( k = _userDefinedProperties.begin() ; k != _userDefinedProperties.end() ; k++ ) {
		found = false;
		for ( l = u.begin() ; l != u.end() ; l++ ) {
			if ( (k->first == l->first) && (k->second == l->second) ) {
				found = true;
				break;
			};
		};
		if (!found) return found;
	};

	// PROFIT!!!
	return true;
};

bool aid::operator!= (aid &other)  {
	return !(*this == other);
};

std::ostream& operator<< (std::ostream& o, aid& a)
 {
   return o << a.asString();
 }

string aid::asString() {
	string sb = "(agent-identifier \n";
	list<string>::iterator i;
	
	sb += ":name ";
	sb += _name;
	sb += "\n";
	sb += ":addresses ";
	sb += "(sequence ";
	sb += "\n";
	for ( i = _addresses.begin() ; i != _addresses.end() ; i++ ) {
		sb += (*i) += " ";
	};
	sb += ")\n";
	for ( i = _resolvers.begin() ; i != _resolvers.end() ; i++ ) {
		sb += (*i) += " ";
	};
	sb += ")\n";
	
	//sb += ")\n";
	
	return sb;
};

int main() {
	list<string> l, ll; 
	l.push_back("alice@wonderland.com");
	ll.push_back("bob@thornton.com");
	aid alice("Alice", l);
	aid bob("Bob", ll);
	
	cout << alice.getName() << " " << bob.getName() << endl ;
	cout << alice.asString() << endl;
	cout << bob.asString() << endl;
	
	if (alice == bob) cout << "EQUALS" << endl;
	if (alice != bob) cout << "NOT EQUALS" << endl;

	cout << alice << endl;
};
